{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第 1 章 用4行代码与大模型对话\n",
    "*****"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以前经常使用搜索引擎来解决问题的你，现在大概率已经在工作中频繁使用大模型了。 但是只在网页聊天框中和大模型对话，终究有一些局限性：比如你在本地有一个超大的用户反馈表格、或者是有一些仅内部可访问的网页，想要借助大模型做一系列处理，就不太好做到了。 幸运的是，现在很多大模型服务提供商，都提供了 API 接口，可以让你方便地实现各种原本在网页聊天框中不方便、或无法实现的功能。\n",
    "\n",
    "本章将通过一个简单的例子，让你快速进入到大模型应用开发的世界。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 准备工作\n",
    "\n",
    "### 1.1. 安装\n",
    "\n",
    "下载文档代码及安装依赖项\n",
    "```bash\n",
    "git clone https://github.com/AlibabaCloudDocs/llm_learning.git\n",
    "cd llm_learning\n",
    "pip install -r requirements.txt\n",
    "```\n",
    "\n",
    "### 1.2. 账号准备\n",
    "\n",
    "首先，您需要前往 [官网创建 API Key](https://help.aliyun.com/zh/dashscope/developer-reference/activate-dashscope-and-create-an-api-key)。接下来，请获取你的 [DASHSCOPE_API_KEY](https://dashscope.console.aliyun.com/apiKey)，\n",
    "\n",
    "####  MacOS or Linux\n",
    "您可以使用以下命令行导入环境变量\n",
    "```bash\n",
    "export DASHSCOPE_API_KEY=\"sk-****\"\n",
    "```\n",
    "\n",
    "#### Windows\n",
    "可以在终端使用[`SET`](https://learn.microsoft.com/zh-cn/windows-server/administration/windows-commands/set_1)命令设置环境变量\n",
    "```bat\n",
    "set DASHSCOPE_API_KEY=sk-****\n",
    "```\n",
    "或者在[`PowerShell`](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-7.4)中使用以下命令行配置环境变量 \n",
    "```powershell\n",
    "$Env:DASHSCOPE_API_KEY = \"sk-****\"\n",
    "```\n",
    "\n",
    "#### Jupyter Notebook\n",
    "您可以使用[`os.environ`](https://docs.python.org/3/library/os.html)方法，在代码开头设置临时环境变量。\n",
    "\n",
    "### 1.3. docenv模式\n",
    "\n",
    "将环境变量写入文件\"~/.zshrc\"中：\n",
    "\n",
    "```bash\n",
    "export OPENAI_API_KEY=\"sk-...\"\n",
    "```\n",
    "就可以执行如下命令 ```source ~/.zshrc``` 将这个环境变量绑定到全局shell中。\n",
    "\n",
    "接下来我们将加载这个环境变量到notebook中。执行如下命令\n",
    "\n",
    "**使用Windows，已经通过Windows PowerShell来注册环境变量的同事可以考虑跳过这里**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Python-dotenv could not parse statement starting at line 7\n",
      "Python-dotenv could not parse statement starting at line 8\n",
      "Python-dotenv could not parse statement starting at line 10\n",
      "Python-dotenv could not parse statement starting at line 11\n",
      "Python-dotenv could not parse statement starting at line 16\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "## for MacOS users\n",
    "filePath = os.path.abspath(os.path.expanduser(os.path.expandvars(\"~/.zshrc\")))\n",
    "load_dotenv(filePath)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# os.environ['DASHSCOPE_API_KEY']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 文本生成实验\n",
    "\n",
    "通过 langchain_community 库中封装的 Tongyi 工具，我们可以通过[灵积API](https://dashscope.console.aliyun.com/apiKey)访问通义千问，让通义千问回答问题。\n",
    "\n",
    "### 2.1. 简单文本生成\n",
    "\n",
    "首先，Tongyi 工具的接口默认是一次性输出全部生成的答案，用户需要等待数秒才能看到完整答案。下面，我们先来看看一次性生成全部答案的代码和执行效果。代码只有三行，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "阿里云成立于2009年9月10日，是阿里巴巴集团旗下的云计算服务品牌，提供包括计算、存储、网络、安全、数据库、大数据、人工智能等全面的云计算服务。\n"
     ]
    }
   ],
   "source": [
    "from langchain_community.llms import Tongyi\n",
    "llm = Tongyi()\n",
    "print(llm.invoke('阿里云成立于什么时间'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 状态码 400 异常问题解决方法\n",
    "如果遇到程序抛出异常，请查看[**状态码**](https://help.aliyun.com/document_detail/2712216.html)\n",
    "\n",
    "例如遇到如下错误信息，请检查你的账户是不是**欠费**了，或者你的API KEY是不是配置错了。\n",
    "```sh\n",
    "ValueError: status_code: 400 \n",
    " code: Arrearage \n",
    " message: Access denied, please make sure your account is in good standing.\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2. 流式文本生成\n",
    "\n",
    "采用LangChain封装的接口来实现流式文本生成，我们需要在创建Tongyi对象时声明采用流式输出（streaming=True），然后用一个循环来接收生成的文本，直到生成的文本为空。\n",
    ">（注意：如果你遇到了 TypeError: Additional kwargs key output_tokens already exists in left dict and value has unsupported type <class 'int'> 这个错误，请参考[github](https://github.com/langchain-ai/langchain/pull/16580)中的说明）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "阿里云作为全球领先的云计算及人工智能科技公司，提供了丰富的云计算产品和服务，有以下几个主要的原因让你可能选择使用阿里云：\n",
      "\n",
      "1. 稳定性：阿里云拥有强大的基础设施和优秀的技术团队，提供高可用、低延迟的云服务，确保业务的稳定运行。\n",
      "\n",
      "2. 安全性：阿里云注重数据安全和隐私保护，提供多种安全防护措施，如DDoS防护、防火墙等，保障用户的数据安全。\n",
      "\n",
      "3. 丰富的产品线：从计算、存储、数据库到大数据、人工智能等，阿里云提供全方位的云服务，满足不同规模企业的需求。\n",
      "\n",
      "4. 弹性扩展：阿里云支持弹性伸缩，可以根据业务需求快速调整资源，避免资源浪费，节省成本。\n",
      "\n",
      "5. 技术支持：阿里云有专业的技术团队，提供24小时的技术支持和服务，帮助企业解决技术问题。\n",
      "\n",
      "6. 全球化布局：阿里云在全球多个地区设有数据中心，可以提供本地化的服务，帮助企业快速拓展全球业务。\n",
      "\n",
      "7. 成功案例：众多企业，包括互联网、金融、制造、零售等行业的头部企业，都在使用阿里云，并取得了显著的效果。\n",
      "\n",
      "8. 开发者友好：阿里云提供了丰富的开发工具和API，方便开发者进行快速开发和集成。\n",
      "\n",
      "综上，阿里云凭借其技术实力、服务质量、全球化视野等多方面优势，成为许多企业和开发者的选择。"
     ]
    }
   ],
   "source": [
    "from langchain_community.llms import Tongyi\n",
    "llm = Tongyi(streaming=True)\n",
    "for chunk in llm.stream('为什么要使用阿里云'):\n",
    "    print(chunk, end=\"\", flush=True)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 封装成文件来访问通义千问\n",
    "\n",
    "我们将上述两端代码功能封装进文件，读者可以直接调用文件来实现与大模型的对话。\n",
    "\n",
    "### 3.1. 批量输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "阿里云成立于2009年9月10日，是阿里巴巴集团旗下的云计算服务品牌，提供包括计算、存储、网络、安全、数据库、大数据、人工智能等全面的云计算服务。阿里云致力于为企业提供一站式的云计算解决方案，帮助企业实现数字化转型和业务增长。经过十多年的快速发展，阿里云已成为全球领先的云计算及人工智能科技公司之一，服务客户遍布全球200多个国家和地区。\n"
     ]
    }
   ],
   "source": [
    "! python main_simple.py \"阿里云是什么时候成立的\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2. 流式输出\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "阿里云作为全球领先的云计算及人工智能科技公司，提供了丰富的云计算、大数据、人工智能等产品和服务，以下是一些使用阿里云的主要原因：\n",
      "\n",
      "1. 技术领先：阿里云拥有强大的技术研发实力，其云计算、大数据、人工智能等技术在全球范围内具有领先地位，能够为企业提供最先进的技术支持。\n",
      "\n",
      "2. 稳定可靠：阿里云的基础设施遍布全球，数据中心分布广泛，提供高可用性和灾备能力，确保业务的稳定运行。其“飞天”大规模操作系统能够处理海量数据和流量，保证服务的稳定性。\n",
      "\n",
      "3. 安全保障：阿里云在数据安全和隐私保护方面有着严格的标准和措施，包括防火墙、DDoS防护、加密技术等，保障用户的数据安全。\n",
      "\n",
      "4. 丰富的产品线：阿里云提供包括云服务器、数据库、存储、CDN、物联网、人工智能等在内的全方位云服务，满足不同行业、不同规模企业的需求。\n",
      "\n",
      "5. 弹性伸缩：基于云计算的弹性伸缩能力，企业可以根据业务需求快速调整资源，避免了传统IT设施的高昂投入和运维成本。\n",
      "\n",
      "6. 成本优化：使用阿里云可以按需付费，大大降低了企业的初始投资和运营成本，尤其对于初创企业和中小型企业来说，更加经济实惠。\n",
      "\n",
      "7. 专业服务：阿里云提供24小时的技术支持和咨询服务，有专业的团队帮助企业解决技术问题，提升效率。\n",
      "\n",
      "8. 生态系统：阿里云构建了一个庞大的开发者和合作伙伴生态系统，可以为企业提供一站式的解决方案，加速业务创新和发展。\n",
      "\n",
      "综上所述，无论从技术实力、服务稳定性、安全性、产品丰富度、成本效益还是生态建设等方面，阿里云都是企业进行数字化转型和业务发展的重要选择。"
     ]
    }
   ],
   "source": [
    "! python main_stream.py \"为什么要使用阿里云\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 总结\n",
    "\n",
    "通过本章的学习，你已经获得了两个与大模型对话聊天的命令行工具！你不仅已经了解了如何使用通义千问的 API，如何流式输出大模型返回的结果，并在本地运行了示例代码。 在开始下一章的学习之前，你也可以尝试调整 prompt 语句，让通义千问回答不同的问题。或者将这段代码集成到其他更复杂的场景中，来帮助你完成任务，比如从一个本地 excel 文件中逐行读取问题，并对其做出回答。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 参考资料\n",
    "- [DashScope](https://dashscope.aliyun.com/)\n",
    "- [LangChain](https://python.langchain.com/docs)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "aiworld",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
